package com.i9he.ping.service.impl;

import static com.i9he.ping.utils.ConfigUtils.configuration;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.i9he.ping.model.IPStatus;
import com.i9he.ping.service.Strategy;
import com.i9he.ping.utils.LoggerUtils;
public class PingThread extends Thread {
	
	private Logger logger = null;

	private final IPStatus ip;

	public PingThread(String ip) {
		this.ip = new IPStatus(ip);
		logger = LoggerUtils.getLoggerByName(ip);
	}

	private void startPing() {
		Pattern pattern = Pattern.compile(configuration.getString("ping.success.regex"));
		try {
			final String command = String.format(configuration.getString("ping.command.text"), ip.getIp());
			final String charset = configuration.getString("ping.command.charset");//GBK
			final int exclute = configuration.getInt("ping.command.result.exclude");//3
			final int count = configuration.getInt("ping.command.count", 0);//10
			final int aveCount0 = configuration.getInt("ping.average.count", 0);//ping值平均每轮次数10次
			final int msDiffer = configuration.getInt("ping.ms.differ", 0);

			Process process = Runtime.getRuntime().exec(command);
//			System.err.println("Start new: " + command);

			try (InputStreamReader reader = new InputStreamReader(process.getInputStream(), charset)) {
				BufferedReader buf = new BufferedReader(new InputStreamReader(process.getInputStream(),charset));
				StringBuilder sb = new StringBuilder();
				String line = null;
				for (int i = 0; i < exclute; i++) {
					line = buf.readLine(); // 丢弃开始启动时命令
				}
				int lineCount = 0;
				int aveCount1 = aveCount0;
				int sum = 0; //毫秒值总和
				int errorCount = 0;
				while ((line = buf.readLine()) != null) {
					if (count > 0 && ++lineCount > count) { //读10行
						ip.setSuccessCount(0); //若在命令行ping 终止之前，都没有网络延迟的情况，
//						ip.setErrorCount(0);  //就把连接成功和错误的次数都清空
						process.destroy();
						break;
					}
					if (StringUtils.isBlank(line)) { //是否读到数据
						continue;
					}
					//读到数据之后
					logger.info(line);
					if (pattern.matcher(line).find()) { //能否匹配到 正则.*时间.*TTL.*
						
						sb.delete(0, sb.length());//全部清空，保证每次只读一行
						sb.append(line);
						
						if(  ( (--aveCount1) - errorCount) < 0){ //
							//十次技术之后
							int indexOf = sb.toString().indexOf("时间=");
							int endIndex = sb.toString().indexOf("ms");
							String s = (String) sb.toString().subSequence(indexOf + "时间=".length(), endIndex);
							if(Math.abs(Integer.parseInt(s) - sum/(aveCount0 - errorCount   )) > msDiffer){ //
								//TODO发邮件
								ip.setSuccessCount(ip.getSuccessCount() + 1);
							}
							sum = 0;  //总和归零
						}
						
						
						System.out.println(sb.toString());
						int indexOf = sb.toString().indexOf("时间=");
						int endIndex = sb.toString().indexOf("ms");
						String s = (String) sb.toString().subSequence(indexOf + "时间=".length(), endIndex);
						sum += Integer.parseInt(s);
						
						ip.setErrorCount(0);
						ip.setSuccessCount(ip.getSuccessCount() + 1);
					} else {
//						ip.setSuccessCount(0);
						ip.setErrorCount(ip.getErrorCount() + 1);
						errorCount++;
					}
					if (strategy != null) {
						strategy.analysisStatus(ip,errorCount);
					}
				}
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	@Override
	public void run() {
		while (true) {
			startPing();
		}
	}

	private Strategy strategy;

	public void setStrategy(Strategy strategy) {
		this.strategy = strategy;
	}
}
